/*************************************************************************************************
 * @brief    闪存管理器
 * Change Logs:
 * Date           Author         Email            Notes
 * 2025-01-10     子恒     3393018959@qq.com    初版完成
 * 2025-06-19     子恒     3393018959@qq.com    奇葩芯片还可以从0写成1，防止此类情况发生
 * 2025-09-10     子恒     3393018959@qq.com    index只在初始化时从flash加载一次，之后随ram更新
 *************************************************************************************************/
#ifndef __B_FLASH_H__
#define __B_FLASH_H__

#include <stdint.h>
#include <stddef.h>
#include "string.h"

#ifdef _B_FLASH_GLOBALS_
#define FLASH_EXTERN
#else
#define FLASH_EXTERN extern
#endif

#define BACK_FUNCTION_EN 1   // 备份功能使能
#define FLASH_READ_MAX_CNT 1 // 最大重读次数

// 日志系统
#define B_FLASH_LOG_DEBUG_EN 0
#define B_FLASH_LOG_INFO_EN 0

#define B_PRINTF(...) printf(__VA_ARGS__)

#if (B_FLASH_LOG_INFO_EN != 0)
#define B_FLASH_INFO_PRINTF(...) B_PRINTF(__VA_ARGS__)
#else
#define B_FLASH_INFO_PRINTF(...)
#endif

#if (B_FLASH_LOG_DEBUG_EN != 0)
#define B_FLASH_DEBUG_PRINTF(...) B_PRINTF(__VA_ARGS__)
#else
#define B_FLASH_DEBUG_PRINTF(...)
#endif

/**
  address:      待擦除页起始地址
  page_number   待擦除页数
*/
typedef int8_t (*flash_erase_page_fn)(uint32_t address, uint32_t page_number);
/**
  address:    待写入地址,需四字节对齐
  write_data：指向待写入数据
  size:       待写入数据字节数
*/
typedef int8_t (*flash_write_words_fn)(uint32_t address, void *write_data, uint32_t size);

/**
  address:    待写入地址,需四字节对齐
  write_data：指向待读取数据
  size:       待读取数据字节数
*/
typedef int8_t (*flash_read_byte_fn)(uint32_t address, void *read_data, uint32_t size);

/*
  p_src:  源数据
  size :  数据长度
  ret:    数据合法性校验
*/
typedef int8_t (*flash_check_fn)(void *p_src, uint32_t size);
typedef int8_t (*flash_set_default_fn)(void *src, uint32_t size);

typedef enum
{
  INDEX_MAIN,
  INDEX_BACK
} index_mode_t;

typedef struct
{
  flash_erase_page_fn pf_erase;    // 擦除函数接口
  flash_write_words_fn pf_write;   // 写函数接口
  flash_read_byte_fn pf_read;      // 读函数接口
  flash_check_fn pf_check;         // 校验函数接口
  flash_set_default_fn pf_default; // 恢复默认值函数接口
  uint32_t main_flash_address;     // 主区起始地址，按页对齐
  uint32_t back_flash_address;     // 备份区起始地址，按页对齐
  uint32_t flash_page_numbre;      // 页数
  uint32_t flash_page_size;        // 页大小
} b_flash_user_init_t;

typedef struct
{
  uint32_t flag_map_number;     // 标识总字数，一个bit标识一个数据
  uint32_t flag_map_bit_number; // 标识总bit数
  uint32_t data_word_number;    // 单个数据块字数
  uint32_t main_index;
  uint32_t back_index;
} b_flash_auto_info_t;

typedef struct
{
  b_flash_user_init_t user_init;
  b_flash_auto_info_t _info;
} b_flash_manager_t;

int8_t b_flash_create(b_flash_manager_t *flash_manager, void *wirte_data, uint32_t size);
int8_t b_flash_write(b_flash_manager_t *flash_manager, void *wirte_data, uint32_t size);
int8_t b_flash_read(b_flash_manager_t *flash_manager, void *read_data, uint32_t size);

// flash管理器，需要多少创建多少
FLASH_EXTERN b_flash_manager_t flash_manager;
#endif
